
package com.jimo.demo;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransAppPayModel;
import com.alipay.api.request.AlipayFundTransAppPayRequest;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipayFundTransAppPayResponse;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;
public class TestController {
    public static void main(String[] args) {
        //用户先获取getAuthParam的值调用支付包获取授权码
//        System.out.println("获取验证信息："+ getAuthParam());
//        System.out.println("获取token(要配置白名单)："+getToken("a7d5ab9846754ccdab5ce6e38001PA85"));
//        System.out.println("获取用户信息PID(要配置isv权限)："+getUserPid("kuaijieB6222adee815f455aad09a02ce2e07X85"));
//        System.out.println("支付串："+ getOrder("2088522444767858"));
    }

    private static String getUserPid(String token) {
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
        certAlipayRequest.setAppId(Config.appid);
        certAlipayRequest.setPrivateKey(Config.privateKey);
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset("UTF8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(Config.certPath);
        certAlipayRequest.setAlipayPublicCertPath(Config.alipayPublicCertPath);
        certAlipayRequest.setRootCertPath(Config.rootCertPath);

        AlipayUserInfoShareRequest request=new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response;
        try {
            DefaultAlipayClient alipayClient=new DefaultAlipayClient(certAlipayRequest);
            response = alipayClient.certificateExecute(request,token);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return response.getBody();
        } else {
            System.out.println("调用失败");
        }
        return null ;
    }
    private static String getToken(String auth_code) {
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
        certAlipayRequest.setAppId(Config.appid);
        certAlipayRequest.setPrivateKey(Config.privateKey);
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset("UTF8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(Config.certPath);
        certAlipayRequest.setAlipayPublicCertPath(Config.alipayPublicCertPath);
        certAlipayRequest.setRootCertPath(Config.rootCertPath);

        AlipaySystemOauthTokenRequest request=new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode(auth_code);
        AlipaySystemOauthTokenResponse response;
        try {
            DefaultAlipayClient alipayClient=new DefaultAlipayClient(certAlipayRequest);
            response = alipayClient.certificateExecute(request);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return response.getBody();
        } else {
            System.out.println("调用失败");
        }
        return null ;
    }
    private static String getAuthParam() {
        Map<String, String> authInfoMap = buildAuthInfoMap(Config.pid, Config.appid, "1234567890");
        String info = buildOrderParam(authInfoMap);
        String sign = getSign(authInfoMap, Config.privateKey);
        return info + "&" + sign;
    }
    public static String buildOrderParam(Map<String, String> map) {
        List<String> keys = new ArrayList<String>(map.keySet());
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keys.size() - 1; i++) {
            String key = keys.get(i);
            String value = map.get(key);
            sb.append(buildKeyValue(key, value, true));
            sb.append("&");
        }

        String tailKey = keys.get(keys.size() - 1);
        String tailValue = map.get(tailKey);
        sb.append(buildKeyValue(tailKey, tailValue, true));

        return sb.toString();
    }
    public static String getSign(Map<String, String> map, String rsaKey) {
        List<String> keys = new ArrayList<>(map.keySet());
        Collections.sort(keys);
        StringBuilder authInfo = new StringBuilder();
        for (int i = 0; i < keys.size() - 1; i++) {
            String key = keys.get(i);
            String value = map.get(key);
            authInfo.append(buildKeyValue(key, value, false));
            authInfo.append("&");
        }
        String tailKey = keys.get(keys.size() - 1);
        String tailValue = map.get(tailKey);
        authInfo.append(buildKeyValue(tailKey, tailValue, false));
        try {
            java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
            signature.initSign(KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64Decoder.decode(rsaKey))));
            signature.update(authInfo.toString().getBytes(StandardCharsets.UTF_8));
            byte[] signed = signature.sign();
            String encodedSign = URLEncoder.encode(Objects.requireNonNull(Base64Encoder.encode(signed)), StandardCharsets.UTF_8);
            return "sign=" + encodedSign;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  null;
    }
    private static String buildKeyValue(String key, String value, boolean isEncode) {
        StringBuilder sb = new StringBuilder();
        sb.append(key);
        sb.append("=");
        if (isEncode) {
            sb.append(URLEncoder.encode(value, StandardCharsets.UTF_8));
        } else {
            sb.append(value);
        }
        return sb.toString();
    }
    public static Map<String, String> buildAuthInfoMap(String pid, String app_id, String target_id) {
        Map<String, String> keyValues = new HashMap<String, String>();

        // 商户签约拿到的app_id，如：2013081700024223
        keyValues.put("app_id", app_id);

        // 商户签约拿到的pid，如：2088102123816631
        keyValues.put("pid", pid);

        // 服务接口名称， 固定值
        keyValues.put("apiname", "com.alipay.account.auth");

        // 服务接口名称， 固定值
        keyValues.put("methodname", "alipay.open.auth.sdk.code.get");

        // 商户类型标识， 固定值
        keyValues.put("app_name", "mc");

        // 业务类型， 固定值
        keyValues.put("biz_type", "openservice");

        // 产品码， 固定值
        keyValues.put("product_id", "APP_FAST_LOGIN");

        // 授权范围， 固定值
        keyValues.put("scope", "kuaijie");

        // 商户唯一标识，如：kkkkk091125
        keyValues.put("target_id", target_id);

        // 授权类型， 固定值
        keyValues.put("auth_type", "AUTHACCOUNT");

        // 签名类型
        keyValues.put("sign_type","RSA2");

        return keyValues;
    }
    private static String getOrder(String uid) {
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
        certAlipayRequest.setAppId(Config.appid);
        certAlipayRequest.setPrivateKey(Config.privateKey);
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset("UTF8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(Config.certPath);
        certAlipayRequest.setAlipayPublicCertPath(Config.alipayPublicCertPath);
        certAlipayRequest.setRootCertPath(Config.rootCertPath);
        DefaultAlipayClient alipayClient;
        try {
            alipayClient = new DefaultAlipayClient(certAlipayRequest);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        AlipayFundTransAppPayRequest request=new AlipayFundTransAppPayRequest();
        AlipayFundTransAppPayModel appPayModel=new AlipayFundTransAppPayModel();
        appPayModel.setOutBizNo("" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
        appPayModel.setProductCode("STD_RED_PACKET");
        appPayModel.setTransAmount("0.1");
        appPayModel.setBizScene("PERSONAL_PAY");
        appPayModel.setOrderTitle("红包来了");
        appPayModel.setRemark("红包来了红包来了红包来了红包来了");
        appPayModel.setBusinessParams("{\"sub_biz_scene\":\"REDPACKET\",\"payer_binded_alipay_uid\":\""+uid+"\"}");
        request.setBizModel(appPayModel);
        System.out.println(appPayModel.getOutBizNo());
        AlipayFundTransAppPayResponse response = null;
        try {
            response = alipayClient.sdkExecute(request);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        return response.getBody();
    }
}
